using Comteck.Dependency;
using Comteck.Dto.Sys;
using Comteck.Dto.Users;
using Comteck.Extensions;
using Comteck.Http;
using Comteck.Idsr4;
using Comteck.Ktt.Services;
using Comteck.Linq;
using Comteck.Utils;
using Comteck.Winforms.AutoMapper;
using Comteck.Winforms.Forms;
using Comteck.Winforms.Infrastructure;
using Comteck.Winforms.Tasks;
using Comteck.Winforms.Utils;
using DevExpress.LookAndFeel;
using ICSharpCode.SharpZipLib.Zip;
using log4net;
using MessagePack.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IO;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using WinformApp = System.Windows.Forms.Application;

namespace Comteck.Winforms {
  /// <summary>
  /// 全局资源信息
  /// </summary>
  public class SysGlobal {
    /// <summary>
    /// 日志
    /// </summary>
    public static ILog Logger = LogManager.GetLogger(typeof(SysGlobal));
    public static RecyclableMemoryStreamManager Manager { get; } = new RecyclableMemoryStreamManager();
    private class HandleMsgErrorHandler : DelegatingHandler {
      public event Action<HttpResponseMessage, string, string> OnVersionCheckFailed;
      public event Action<HttpResponseMessage, string> OnAuthenticationFailed;
      protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) {
        var context = System.Threading.SynchronizationContext.Current;
        if (context != null)
          System.Threading.SynchronizationContext.SetSynchronizationContext(null);
        try {
          var response = await base.SendAsync(request, cancellationToken);

          if (!response.IsSuccessStatusCode) {
            if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden) {
              OnAuthenticationFailed?.Invoke(response, response.ReasonPhrase);
            }
            return response;
          }
          var stream = await response.Content.ReadAsStreamAsync();
          if (!stream.CanSeek) {
            var copyedStream = Manager.GetStream("http");
            await stream.CopyToAsync(copyedStream, 81920, cancellationToken);
            using (stream)
              copyedStream.Seek(0, SeekOrigin.Begin);
            stream = copyedStream;
            var originContent = response.Content;
            response.Content = new StreamContent(copyedStream);
            originContent.Headers.CopyTo(response.Content.Headers);
          }
          int? code = null;
          string msg = null;
          string versionData = null;
          switch (response.Content.Headers.ContentType.MediaType) {
            case ComteckConstants.CONTENTTYPE_JSON:
              var obj = JToken.Parse(await stream.ReadAsStringAsync());
              code = obj["code"].To<int>();
              msg = obj["message"].To<string>();
              versionData = obj["versionData"].To<string>();
              break;
            case ComteckConstants.CONTENTTYPE_MSGPACK:
            case ComteckConstants.CONTENTTYPE_X_MSGPACK:
              var msgPackObj = stream.DeserializeMessagePack<Dictionary<string, object>>();
              code = Convert.ToInt32(msgPackObj["Code"]);
              msg = (string)msgPackObj["Message"];
              versionData = (string)msgPackObj["VersionData"];
              break;
            default: break;
          }
          stream.Seek(0, SeekOrigin.Begin);
          if (code == SmartRetailConstants.RESPONSECODE_VERSION) {
            OnVersionCheckFailed?.Invoke(response, msg, versionData);
          } else if (code == SmartRetailConstants.RESPONSECODE_UNAUTHORIZED) {
            OnAuthenticationFailed?.Invoke(response, msg);
          }
          stream.Seek(0, SeekOrigin.Begin);
          return response;
        } catch (OperationCanceledException) {
          throw;
        } catch (Exception ex) {
          Logger.Error(null, ex);
          throw;
        } finally {
          if (context != null)
            System.Threading.SynchronizationContext.SetSynchronizationContext(context);
        }
      }
    }
    #region 配置信息

    public const string INVENTORY_DEVICE_WORK_BASE_PATH = "InventoryDevice";
    private static Font currentFont = null;
    public static Font CurrentFont => currentFont ?? DevExpress.Utils.AppearanceObject.DefaultFont;
    public static void SetSystemFontFamaily(string family) {
      var font = new Font(family, CurrentFont.Size, CurrentFont.Style, CurrentFont.Unit, CurrentFont.GdiCharSet);
      // 设置默认字体
      if (currentFont == null) {
        UserLookAndFeel.Default.StyleChanged += (s, e) => {
          DevExpress.Utils.AppearanceObject.DefaultMenuFont = currentFont;
          DevExpress.Utils.AppearanceObject.DefaultFont = currentFont;
        };
      }
      currentFont = font;
      DevExpress.Utils.AppearanceObject.DefaultMenuFont = currentFont;
      DevExpress.Utils.AppearanceObject.DefaultFont = currentFont;
    }

    #endregion


    #region  web api

    /// <summary>
    /// 
    /// </summary>
    public static AppFormSettings Settings { get; set; }
    private static readonly HttpMessageHandler httpMessageHandler;
    /// <summary>
    /// HttpClient
    /// </summary>
    public static HttpClient HttpClient { get; set; }
    
    public static ProgressMessageHandler CreateProgressMessageHandler() {
      return new ProgressMessageHandler(new HttpClientHandler() {
        AllowAutoRedirect = false,
        UseProxy = false,
        AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
      });
    }

    #endregion

    #region 登录信息

    /// <summary>
    /// Identity Response
    /// </summary>
    public static IdentityResponse IdentityResponse { get; set; }

    /// <summary>
    /// 登录用户
    /// </summary>
    public static UserDto LoginUser { get; set; }

    /// <summary>
    /// 已加载的程序集
    /// </summary>
    public static Assembly[] LoadedAssemblys { get; set; }

    /// <summary>
    /// 公网IP
    /// </summary>
    public static ClientAndIPInfo ClientAndIPInfo = new ClientAndIPInfo();

    /// <summary>
    /// 是否支持web sockets
    /// </summary>
    public static bool IsWebSocketsSupported { get; set; } = true;

    /// <summary>
    /// 全局菜单列表
    /// </summary>
    public static CKBindingList<MenuAuthDto> MenuList { get; set; } = new CKBindingList<MenuAuthDto>();

    #endregion

    #region 登录界面和主界面

    /// <summary>
    /// 登录界面的类型
    /// </summary>
    public static Type LoginFormType { get; set; }

    /// <summary>
    /// 登录界面
    /// </summary>
    public static Form LoginForm => AssemblyHelper.CreateInstance(LoginFormType) as Form;

    /// <summary>
    /// 主程序
    /// </summary>
    public static FrmSkinBase MainForm { get; set; }

    /// <summary>
    /// Logo图片
    /// </summary>
    public static Image LogoImage { get; set; }

    #endregion

    #region 队列信息

    /// <summary>
    /// 【商品档案】任务管理器
    /// </summary>
    public static TaskManager GoodsTaskManager { get; set; }

    /// <summary>
    /// 【商品档案】任务管理器
    /// </summary>
    public static TaskManager GoodsExtraTaskManager { get; set; }

    /// <summary>
    /// 【商品档案】任务管理器
    /// </summary>
    public static TaskManager OrgGoodsTaskManager { get; set; }

    /// <summary>
    /// 【商品档案】任务管理器
    /// </summary>
    public static TaskManager GoodsBarcodeTaskManager { get; set; }

    /// <summary>
    /// 【主档库】任务管理器
    /// </summary>
    public static TaskManager ArchivesTaskManager { get; set; }

    /// <summary>
    /// 【非主档库】任务管理器
    /// </summary>
    public static TaskManager OtherTaskManager { get; set; }

    /// <summary>
    /// 【本地库】任务管理器
    /// </summary>
    public static TaskManager LocalTaskManager { get; set; }

    /// <summary>
    /// 【其他】任务管理器
    /// </summary>
    public static TaskManager CommonTaskManager { get; set; }

    #endregion

    /// <summary>
    /// Ioc容器
    /// </summary>
    public static IServiceProvider ServiceProvider { get; set; }

    ///// <summary>
    ///// 默认皮肤
    ///// </summary>
    //public static string DevSkinName = null;

    /// <summary>
    /// 网络是否通畅
    /// </summary>
    public static bool IsNetworkOnline { get; set; } = false;

    /// <summary>
    /// 定时器
    /// </summary>
    private static System.Threading.Timer localData_Timer = null;

    /// <summary>
    /// token刷新定时器
    /// </summary>
    private static System.Threading.Timer TokenRefresh_Timer = null;

    /// <summary>
    /// GC 刷新定时器
    /// </summary>
    private static System.Threading.Timer GC_Timer = null;

    /// <summary>
    /// https://www.cnblogs.com/songxingzhu/p/5343905.html
    /// </summary>
    public static System.Threading.SynchronizationContext SynchronizationContext = null;

    /// <summary>
    /// 是否释放
    /// </summary>
    public static bool IsDisposed { private set; get; } = false;

    /// <summary>
    /// 菜单的图片集合
    /// </summary>
    public static FileInfo[] ImagesFileList {
      get;
      set;
    }

    public static SizeF DpiSizeF;

    static SysGlobal() {
      // 是否支持websockets
      IsWebSocketsSupported = WinformHelper.IsWebSocketsSupported();
      //IsWebSocketsSupported = false;

      var handler = new HttpClientHandler() {
        AllowAutoRedirect = false,
        UseProxy = false,
        AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
      };
      var handleErrorHandler = new HandleMsgErrorHandler() {
        InnerHandler = handler
      };
      handleErrorHandler.OnVersionCheckFailed += (response, msg, versionData) => {
        WinformStartUpHelper.OpenForm_VersionCheck(versionData);
      };
      handleErrorHandler.OnAuthenticationFailed += (response, msg) => {
        WinformStartUpHelper.OpenForm_Unauthorized();
      };
      httpMessageHandler = handleErrorHandler;

      // dpi缩放比例
      DpiSizeF = WinformHelper.GetDpiSizeF();
    }

    #region 1、加载配置信息

    /// <summary>
    /// 加载公用配置信息
    /// </summary>
    public static void LoadAppSettings() {
      // 加载公用配置信息
      Settings = ConfigManagerHelper.LoadAll<AppFormSettings>();
      Settings.AppName_HubCenter = "HubCenter";
      Settings.AppName_HubCenter_Name = "datahub";
      Settings.AppName_Identity = "Identity";
      Settings.AppName_Archives = "Archives";
      Settings.AppName_Supply = "Supply";
      Settings.AppName_Customer = "Customer";
      Settings.AppName_Market = "Market";
      Settings.AppName_Sales = "Sales";
      Settings.AppName_Storages = "Storages";
      Settings.AppName_Schedules = "Schedules";
      Settings.AppName_Finances = "Finances";
      Settings.AppName_Reports = "Reports";
      Settings.AppName_MultiChannel = "MultiChannel";
      Settings.AppName_FinancesSystem = "FinancesSystem";
      Settings.AppName_OrderSystems = "OrderSystems";
      Settings.AppName_DWH = "DWH";
      Settings.AppName_BigData = "BigData";

      Settings.LocalData_Interval = Settings.LocalData_Interval <= 0 ? 5 : Settings.LocalData_Interval;
      Settings.SignalR_Interval = Settings.SignalR_Interval <= 0 ? 1 : Settings.SignalR_Interval;
      Settings.GC_Collect_Interval = Settings.GC_Collect_Interval <= 0 ? 1 : Settings.GC_Collect_Interval;

      Settings.LogoPath = Settings.LogoPath.IsNullOrEmpty() ? @"\Resources\logo\Logo.png" : Settings.LogoPath;
    }
    #endregion

    #region 3、初始化

    /// <summary>
    /// 初始化
    /// </summary>
    public static void Initialize(Action<ServiceCollection> action) {
      SynchronizationContext = new WindowsFormsSynchronizationContext();

      //// 检查网络情况
      //IsNetworkOnline = InternetHelper.Ping() != 0;

      //// 加载APP设置
      //LoadAppSettings();
      try {
        AutoMapperContainer.Instance.Initialize();
      } catch (ReflectionTypeLoadException ex) {
        foreach (var ex1 in ex.LoaderExceptions) {
          Logger.InfoFormat(ex1.GetMessage());
        }
        // 这里不抛出错误，优先保证升级程序能执行 by weijie.sun 2024/06/23
        //throw ex;
      }

      // 本地信息
      //ClientAndIPInfo.ClientIp = SystemDeviceHelper.GetHostAddress_IPV4();
      //ClientAndIPInfo.ClientSN = SystemDeviceHelper.GetMacAddress();
      //ClientAndIPInfo.ClientName = SystemDeviceHelper.ComputerName;
      //ClientAndIPInfo.InternetIp = InternetHelper.GetPublicNetworkIp(2);

      // 已加载的程序集
      LoadAssemblys();

      // api url
      //InitHttpClient();

      ServiceProvider = WinformBootstrapper.ConfigureServices(action);

      // 初始化队列
      CommonTaskManager = new TaskManager() { Name = "Common", LogEnabled = false };

      localData_Timer = new System.Threading.Timer((state) => {
        // 暂时不定时拉数据
        //LocalDbDataHelper.PollingServerData();
      });

      // gc
      GC_Timer = new System.Threading.Timer((state) => {
        CommonTaskManager.Enqueue(new Task(() => {
          WinformHelper.ClearMemory();
        }));
      });
    }


    /// <summary>
    /// 
    /// </summary>
    public static void StartProcess() {
      // 启动轮询数据
      Logger.Info("本地数据轮询启动");
      localData_Timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(Settings.LocalData_Interval));
      TokenRefresh_Timer.Change(TimeSpan.Zero, TimeSpan.FromHours(2));
      GC_Timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(Settings.GC_Collect_Interval));
    }


    /// <summary>
    /// 
    /// </summary>
    public static void LoadAssemblys() {
      LoadedAssemblys = AppDomain.CurrentDomain.GetAssemblies().OrderBy(x => x.FullName).ToArray();
      Logger.Info($"一共加载 {LoadedAssemblys.Length} 程序集");

      //#if DEBUG
      //      foreach (var assemby in LoadedAssemblys) {
      //        Logger.Info($"{assemby.FullName}");
      //      }
      //#endif

    }

    /// <summary>
    /// set api url
    /// </summary>
    public static void InitHttpClient() {
      // 初始化HttpClient
      HttpClient = new HttpClient(httpMessageHandler) {
        Timeout = TimeSpan.FromMinutes(10),
        BaseAddress = new Uri(Settings.GatewayUrl)
      };
      // 头部信息
      HttpClient.DefaultRequestHeaders.Add(SmartRetailConstants.HEAD_TENANTCODE, Settings.Tenant_Code);
      HttpClient.DefaultRequestHeaders.Add(SmartRetailConstants.HEAD_VERSIONCODE, Settings.Version);
#if DEBUG
      // 调试模式下忽略版本更新
      HttpClient.DefaultRequestHeaders.Add(SmartRetailConstants.HEAD_IGNORE_VERSIONCHECK, "1");
#endif
      // format
      HttpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue(DecompressionMethods.GZip.ToString().ToLower()));
      HttpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue(DecompressionMethods.Deflate.ToString().ToLower()));


      // 设置头部认证信息，等同于 OidcConstants.AuthenticationSchemes.AuthorizationHeaderBearer
      // client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
      HttpClient.SetBearerToken(IdentityResponse?.Access_Token);

      // 针对response编码做的一个拦截器
      //HttpClientExtentions.AjaxResponseIntercept = LocalDbDataHelper.HandleHttpResponseResult;
    }

    #endregion

    #region 更新update文件

    /// <summary>
    /// 更新update文件
    /// </summary>
    public static void ReplaceUpdateExe() {
      // 更新文件名称
      var updateName = Settings.UpdateProgramName;
      if (updateName.IsNullOrEmpty()) {
        return;
      }
      var updatePath = $"{WinformApp.StartupPath}\\{updateName}";

      // 查找根目录下的替换的更新文件是否存在
      var replaceUpdateName = $"{updateName}.new";
      var replaceUpdatePath = $"{WinformApp.StartupPath}\\{replaceUpdateName}";

      // 如果替换文件不存在，则不做处理
      if (File.Exists(replaceUpdatePath) == false) {
        return;
      }

      // 替换原有的文件
      try {
        // 拷贝到原文件
        if (File.Exists(updatePath)) {
          File.Copy(replaceUpdatePath, updatePath, true);

          // 删除原文件
          File.Delete(replaceUpdatePath);
        } else {
          // 移动
          File.Move(replaceUpdatePath, updatePath);
        }
      } catch (Exception ex) {
        Logger.Error("更新update文件失败", ex);
      }

    }

    #endregion

    #region 更新替换数据库文件

    /// <summary>
    /// 更新替换数据库文件
    /// </summary>
    public static void ReplaceLocalDb() {
      try {
        // 数据库文件
        var fileName = $"{WinformApp.StartupPath}\\data-backup.zip";

        // 解压缩文件
        if (UnZipFile(fileName) == false) {
          return;
        }

        // 拷贝文件
        var from = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName));
        CopyDirectory(from, WinformApp.StartupPath);

        // 删除已经解压锁文件
        Directory.Delete(from, true);

        // 删除刚下载的文件
        File.Delete(fileName);
      } catch (Exception ex) {
        Logger.Error("替换本地数据库文件失败", ex);
      }
    }

    /// <summary>
    /// 解压缩文件
    /// </summary>
    /// <param name="filePath"></param>
    private static bool UnZipFile(string zipFilePath) {
      if (!File.Exists(zipFilePath)) {
        return false;
      }

      // 先将存在的目录删除掉
      var path = Path.Combine(Path.GetDirectoryName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
      if (Directory.Exists(path)) {
        Directory.Delete(path, true);
      }

      // create new
      Directory.CreateDirectory(path);

      // 解压缩文件
      using (var s = new ZipInputStream(File.OpenRead(zipFilePath))) {
        ZipEntry theEntry;
        while ((theEntry = s.GetNextEntry()) != null) {

          if (theEntry.IsDirectory) {
            var directoryName = Path.Combine(path, theEntry.Name);

            // create directory 
            if (!Directory.Exists(directoryName)) {
              Directory.CreateDirectory(directoryName);
            }
          }

          if (theEntry.IsFile) {
            var fileName = Path.Combine(path, theEntry.Name);

            if (fileName != string.Empty) {
              using (var fs = File.Create(fileName)) {

                var size = 1024 * 8;
                var readByte = 0;
                var data = new byte[size];
                while (true) {
                  readByte = s.Read(data, 0, data.Length);
                  if (readByte > 0) {
                    fs.Write(data, 0, readByte);
                  } else {
                    break;
                  }
                }// end while
                fs.Close();
              }//end using
            }//end if
          }//end if
        }
      }

      return true;
    }

    /// <summary>
    /// 拷贝文件
    /// </summary>
    /// <param name="sourcePath"></param>
    /// <param name="destinationPath"></param>
    private static void CopyDirectory(string sourcePath, string destinationPath) {
      if (!Directory.Exists(sourcePath)) {
        return;
      }
      var info = new DirectoryInfo(sourcePath);
      if (!Directory.Exists(destinationPath)) {
        Directory.CreateDirectory(destinationPath);
      }

      // 循环拷贝
      foreach (var fsi in info.GetFileSystemInfos()) {
        var destName = Path.Combine(destinationPath, fsi.Name);

        //如果是文件，复制文件
        if (fsi is FileInfo) {
          File.Copy(fsi.FullName, destName, true);
        } else {
          //如果是文件夹，新建文件夹，递归
          if (!Directory.Exists(destName)) {
            Directory.CreateDirectory(destName);
          }
          CopyDirectory(fsi.FullName, destName);
        }
      }
    }

    #endregion

    #region 登出及关闭

    /// <summary>
    /// 释放全局内存
    /// </summary>
    public static async Task Logout() {
      // 退出服务端
      //await ServerDbDataHelper.Logout();

      // 关闭本窗口
      MainForm?.Hide();

      LoginUser = null;
      localData_Timer.Change(-1, -1);
      Logger.Info("本地数据轮询停止");
      TokenRefresh_Timer.Change(-1, -1);
      GC_Timer.Change(-1, -1);
      IdentityResponse = null;

      // 弹出登陆窗口
      LoginForm?.ShowDialog();

      // 关闭
      MainForm?.Close();
    }

    /// <summary>
    /// 锁屏
    /// </summary>
    public static void LockScreen() {
      // 隐藏本窗口
      // 取消隐藏窗口
      //MainForm?.Hide();
    }

    /// <summary>
    /// 取消锁屏
    /// </summary>
    public static void UnLockScreen() {
      // 显示本窗口
      // 取消显示窗口
      //MainForm?.Show();
    }

    public static void Reset() {
      // 关闭监听器
      if (localData_Timer != null) {
        localData_Timer.Change(-1, -1);
        localData_Timer.Dispose();
        Logger.Info("本地数据轮询停止并释放");
        localData_Timer = null;
      }

      // 关闭监听器
      if (TokenRefresh_Timer != null) {
        TokenRefresh_Timer.Change(-1, -1);
        TokenRefresh_Timer.Dispose();
        Logger.Info("定时刷新token停止被释放");
        TokenRefresh_Timer = null;
      }

      // 关闭监听器
      if (GC_Timer != null) {
        GC_Timer.Change(-1, -1);
        GC_Timer.Dispose();
        Logger.Info("定时清理内存停止被释放");
        GC_Timer = null;
      }

      // 释放资源
      if (ArchivesTaskManager != null) {
        ArchivesTaskManager.Dispose();
        ArchivesTaskManager = null;
      }

      if (GoodsTaskManager != null) {
        GoodsTaskManager.Dispose();
        GoodsTaskManager = null;
      }

      if (GoodsExtraTaskManager != null) {
        GoodsExtraTaskManager.Dispose();
        GoodsExtraTaskManager = null;
      }

      if (OrgGoodsTaskManager != null) {
        OrgGoodsTaskManager.Dispose();
        OrgGoodsTaskManager = null;
      }

      if (GoodsBarcodeTaskManager != null) {
        GoodsBarcodeTaskManager.Dispose();
        GoodsBarcodeTaskManager = null;
      }

      if (OtherTaskManager != null) {
        OtherTaskManager.Dispose();
        OtherTaskManager = null;
      }
      if (LocalTaskManager != null) {
        LocalTaskManager.Dispose();
        LocalTaskManager = null;
      }

      if (CommonTaskManager != null) {
        CommonTaskManager.Dispose();
        CommonTaskManager = null;
      }

      // 关闭连接
      //LocalDbContainer.Dispose();
      Logger.Info("关闭数据库连接");
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="forceExit">是否强制退出</param>
    public static void Close(bool forceExit = false) {
      if (IsDisposed) {
        return;
      }

      IsDisposed = true;

      Reset();

      Logger.Info("退出系统 开始");

      if (forceExit) {
        Logger.Info("退出系统 成功");
        // 强制退出，这是最彻底的退出方式，不管什么线程都被强制退出，把程序结束的很干净。 
        System.Environment.Exit(0);
      } else {
        // 强制所有消息中止，退出所有的窗体，但是若有托管线程（非主线程），也无法干净地退出； 
        WinformApp.Exit();
        Logger.Info("退出系统 成功");
      }
    }

    #endregion

    #region 动态加载表单

    /// <summary>
    /// 创建表单
    /// </summary>
    /// <param name="assembly_name"></param>
    /// <param name="form_path"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public static FrmBase CreateInstance(string assembly_name, string form_path, params object[] args) {
      // 路径不存在
      if (string.IsNullOrWhiteSpace(form_path) || string.IsNullOrWhiteSpace(assembly_name)) {
        return null;
      }

      // 加载程序集
      var assembly = SysGlobal.LoadedAssemblys.FirstOrDefault(x => x.GetName().Name == assembly_name);

      if (assembly == null) {
        try {
          assembly = Assembly.Load(assembly_name);
          SysGlobal.LoadAssemblys();
        } catch (Exception ex) {
          Logger.Error("加载程序集 {0} 失败".FormatWith(assembly_name), ex);
          return null;
        }
      }

      if (assembly == null) {
        return null;
      }

      // 从程序集创建对象
      var type = assembly.GetType(form_path);
      if (type == null) {
        return null;
      }

      return AssemblyHelper.CreateInstance(type, args) as FrmBase;
    }

    #endregion

  }
}
